package nickthissen.iracing.activities;

import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.Toast;

import com.actionbarsherlock.app.ActionBar;

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;

import nickthissen.iracing.common.DataLoader;
import nickthissen.iracing.common.Error;
import nickthissen.iracing.common.PrivateStore;
import nickthissen.iracing.common.Redirect;
import nickthissen.iracing.common.ServiceLogging;
import nickthissen.iracing.common.Task;
import nickthissen.iracing.datamodels.Result;
import nickthissen.iracing.datamodels.User;
import nickthissen.iracing.iracingforum2.R;
import nickthissen.iracing.networking.NetworkMethod;
import nickthissen.iracing.networking.Networking;
import nickthissen.iracing.parsing.LoginParser;


public class LoginActivity extends TaskActivity
{
    private static final String USER = "USER";
    private static final String REDIRECT = "REDIRECT";

	private ProgressDialog dialog;
	
	private EditText txtUsername, txtPassword;
	private CheckBox chkRemember;
	private Button btnLogin;

    private User attemptingUser;
	
	private Redirect redirect;
	
	@Override
	protected void onCreate(Bundle savedInstanceState) 
	{
		super.onCreate(savedInstanceState);
		setContentView(R.layout.login);

		ActionBar actionBar = this.getSupportActionBar();
		actionBar.setTitle("iRacing Forum - Login");

        // Setup UI
		txtUsername = (EditText) this.findViewById(R.id.txtUsername);
		txtPassword = (EditText) this.findViewById(R.id.txtPassword);
		chkRemember = (CheckBox) this.findViewById(R.id.chkRememberLogin);
		btnLogin = (Button) this.findViewById(R.id.btnLogin);

        // Get redirect if any
        Bundle bundle = this.getIntent().getExtras();
        if (bundle.containsKey(REDIRECT))
        {
            redirect = (Redirect)bundle.getSerializable(REDIRECT);
        }

		// Load stored credentials
		User user = PrivateStore.getStoredLogin(this);

		if (user != null)
		{
			txtUsername.setText(user.username);
			txtPassword.setText(user.password);
            chkRemember.setChecked(true);

            tryLogin();
		}
		
		btnLogin.setOnClickListener(new View.OnClickListener() {
			public void onClick(View v) {
				tryLogin();
			}
		});
	}

    @Override
    protected Task<User> createTask()
    {
        return new Task<User>(this, loader);
    }

    @Override
    protected void saveTaskInput(Bundle state)
    {
        state.putSerializable(USER, attemptingUser);
    }

    @Override
    public Object restoreTaskInput(Bundle state)
    {
        return state.getSerializable(USER);
    }

    public static Intent getIntent(Context context, Redirect redirect)
    {
        Intent intent = new Intent(context, LoginActivity.class);
        Bundle extras = new Bundle();
        extras.putSerializable(REDIRECT, redirect);
        intent.putExtras(extras);
        return intent;
    }

	private void tryLogin()
	{
		User user = new User();
		user.username = txtUsername.getText().toString();
		user.password = txtPassword.getText().toString();
		
		// Reset errors
		txtUsername.setError(null);
		txtPassword.setError(null);
		
		boolean cancel = false;
		View focus = null;
		
		// Check if submitted
		if (TextUtils.isEmpty(user.username)) {
			txtUsername.setError("Please submit your email address.");
			focus = txtUsername;
			cancel = true;
		}
		if (TextUtils.isEmpty(user.password)) {
			txtPassword.setError("Please submit your password.");
			focus = txtPassword;
			cancel = true;
		}
		
		if (cancel) 
		{
			focus.requestFocus();
		} 
		else 
		{
			// Start network task to login	
			dialog = ProgressDialog.show(this, "", "Logging in...");
            dialog.setCancelable(true);
            dialog.setCanceledOnTouchOutside(false);
            dialog.setOnCancelListener(new DialogInterface.OnCancelListener() {
                public void onCancel(DialogInterface dialog) {
                    onCancelTask();
                    dialog.dismiss();
                }
            });
            this.runTask(user);
		}
	}
	
	private void handleLoginAttempt(Result result, User user)
	{
		if (dialog != null)
		{
			dialog.dismiss();
			dialog = null;
		}
		User.currentUser = null;
		
		if (result == null) {
			// Should never happen
			Toast.makeText(this, "Unknown error", Toast.LENGTH_LONG).show();
			return;
		} 
		
		if (result.Success) 
		{
            LoginParser.LoginResult loginResult = (LoginParser.LoginResult)result;

            switch (loginResult.Status)
            {
                case LoginParser.LOGIN_CORRECT:
                    login(user);
                    break;
                case LoginParser.LOGIN_INCORRECT_CREDENTIALS:
                    incorrect();
                    break;
                case LoginParser.LOGIN_MAINTENACE:
                    maintenance(loginResult.Response);
                    break;
                case LoginParser.LOGIN_PITSTOP:
                    error(loginResult.Response);
                    break;
                case LoginParser.LOGIN_ERROR:
                    error(loginResult.Response);
                    break;
            }
		} 
		else
		{
			// Error
			Error error = Error.fromResult(result);
			error.report(this);
		}
	}
	
	private void login(User user)
	{
		// Correct login, store and send to main activity
		User.currentUser = user;

        ServiceLogging.logLogin(this, user);

        if (chkRemember.isChecked())
		{
			PrivateStore.storeLogin(this, user);
            PrivateStore.storeCookies(this, NetworkMethod.getCookieStore(), user.username);
		}
		
		Intent i = MainActivity.getIntent(this, redirect, false);
		this.startActivity(i);
	}

    private void incorrect()
    {
        User.currentUser = null;
        AlertDialog.Builder builder = new AlertDialog.Builder(this);
        builder.setTitle("Invalid credentials").setMessage("The email address and/or password you supplied seem to be incorrect.")
                .setPositiveButton("OK", new DialogInterface.OnClickListener()
                {
                    @Override
                    public void onClick(DialogInterface dialog, int which)
                    {
                        dialog.dismiss();
                    }
                })
                .show();
    }

    private void maintenance(String message)
    {
        Intent i = MaintenanceActivity.getIntent(this, message);
        this.startActivity(i);
    }

    private void error(String html)
    {
        Intent i = LoginErrorActivity.getIntent(this, html);
        this.startActivity(i);
    }

    private DataLoader<User> loader = new DataLoader<User>()
    {
        public Result getData(User in)
        {
            Log.i("Login", "Start login request");
            attemptingUser = in;
            Result result = Networking.login(this.getContext(), in);
            Log.i("Login", "Finished login request");

            if (result != null && result.Success)
            {
                // Parse login result page source to see if correct credentials
                String source = (String) result.Object;
                LoginParser parser = new LoginParser();
                parser.context = this.getContext();
                result = parser.parse(source);
            }

            return result;
        }

        public void onFinished(Result out)
        {
            handleLoginAttempt(out, attemptingUser);
        }

    };
}
